package com.finalist.util.ZXingUtil;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;

import org.apache.log4j.Logger;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.NotFoundException;
import com.google.zxing.Result;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

public class ZXingUtil {
	
	protected static Logger logger = Logger.getLogger(ZXingUtil.class);
    private static final String FORMAT = "png";
    private static final int WIDTH = 200;
    private static final int HEIGHT = 200;
    
    /**
     * 
     * @param imagePath 绝对路径
     * @param logoPath 绝对路径
     * @throws IOException
     */
    public static void overlapImage(String imagePath, String logoPath) throws IOException {    
    	overlapImage(imagePath, new FileInputStream(logoPath));
    }
    
    /**
     * 
     * @param imagePath 绝对路径
     * @param ins
     * @throws IOException
     */
    public static void overlapImage(String imagePath, InputStream ins) throws IOException {    
    	BufferedImage image = ImageIO.read(new File(imagePath));    
    	int logoWidth = image.getWidth() / 6;   //设置logo图片宽度为二维码图片的五分之一    
    	int logoHeight = image.getHeight() / 6; //设置logo图片高度为二维码图片的五分之一    
    	int logoX = (image.getWidth() - logoWidth) / 2;   //设置logo图片的位置,这里令其居中    
    	int logoY = (image.getHeight() - logoHeight) / 2; //设置logo图片的位置,这里令其居中    
    	Graphics2D graphics = image.createGraphics();    
    	graphics.drawImage(ImageIO.read(ins), logoX, logoY, logoWidth, logoHeight, null);
    	
    	graphics.setStroke(new BasicStroke(2));
        graphics.setColor(Color.BLACK);
        graphics.drawRect(logoX, logoY, logoWidth, logoHeight);
        
    	graphics.dispose();    
    	ImageIO.write(image, imagePath.substring(imagePath.lastIndexOf(".") + 1), new File(imagePath));
    }    
    
    /**
     * 
     * @param content
     * @param width
     * @param height
     * @param format jpg 或者 pgn
     * @param destFile 绝对路径
     * @param logoPath 绝对路径
     */
    public static void generateQRCodeImage(String content, int width, int height, String format, String destFile, String logoPath) {
    	try {
    		Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType,Object>();
    		hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
    		hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
    		BitMatrix matrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
    		
    		MatrixToImageConfig config = new MatrixToImageConfig(0xFF000001, 0xFFFFFFFF);
    		
    		//预先判定文件夹是否存在，不存在就先创建
    		File file = new File(destFile);
    		if(!file.exists()){
    			file.mkdirs();
    		}
    		
    		MatrixToImageWriter.writeToFile(matrix, format, file, config); 
    		
    		if(logoPath != null) {
    			overlapImage(destFile, logoPath);
    		}
    	} catch(Exception e) {
    		logger.error("generateCodeImg error: ", e);
    	}
    }
    
    /**
     * 
     * @param content
     * @param width
     * @param height
     * @param destFile 绝对路径
     * @param logoPath 绝对路径
     */
    public static void generateCodeImg(String content, int width, int height, String destFile, String logoPath) {
    	generateQRCodeImage(content, width, height, FORMAT, destFile, logoPath);
    }
    
    /**
     * 
     * @param content
     * @param destFile 绝对路径
     * @param logoPath 绝对路径
     */
    public static void generateCodeImg(String content, String destFile, String logoPath) {
    	generateQRCodeImage(content, WIDTH, HEIGHT, FORMAT, destFile, logoPath);
    }
    
    /**
     * 
     * @param imagePath 绝对路径
     * @param charset
     * @return
     */
    public static String decodeQRCodeImage(String imagePath, String charset) {    
        BufferedImage image = null;    
        try {    
            image = ImageIO.read(new File(imagePath));    
        } catch (IOException e) {    
        	logger.error("decode error: ", e);
            return "";
        }    
        if(null == image){    
        	logger.error("Could not decode QRCodeImage");    
            return "";
        }    
        BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(image)));
        Map<DecodeHintType, String> hints = new HashMap<DecodeHintType, String>();
        hints.put(DecodeHintType.CHARACTER_SET, charset==null ? "UTF-8" : charset);
        Result result = null;
        try {
            result = new MultiFormatReader().decode(bitmap, hints);
            return result.getText();
        } catch (NotFoundException e) {    
        	logger.error("decode error: ", e); 
            return "";    
        }    
    }    

	public static void main(String[] args) throws Exception {
		String content = "http://mp.weixin.qq.com/s?__biz=MTI0MDU3NDYwMQ==&mid=214750197&idx=1&sn=f3726f961f79e3aea23eff3576fb552c&scene=2&from=timeline&isappinstalled=0#rd";
		String logoPath = "F:\\Fengke_logo.png";
		String dest = "F:\\Fengke_ZxingUtil.png";
		
		String s1 = "helloWorld";
		String s2 = "http://mp.weixin.qq.com/" + s1 + ".page";
		System.out.println(s2);
		
		try {
			generateCodeImg(content, 300, 300, dest, logoPath);
    	} catch(Exception e) {
    		logger.error("generateCodeImg error: ", e);
    	} 
	}

}
